home *** CD-ROM | disk | FTP | other *** search
/ Deutsche Edition 1 / Deutsche Edition 1.iso / amok / amok_lha / amok24.lha / Clusters / Clusters.mod < prev    next >
Text File  |  1993-08-15  |  7KB  |  249 lines

  1. (**********************************************************************
  2.  
  3.     :Program.    Clusters.mod
  4.     :Contents.   Block oriented memory management
  5.     :Author.     Nicolas Benezan [bne]
  6.     :Address.    Postwiesenstr. 2, D7000 Stuttgart 60
  7.     :Phone.      711/333679
  8.     :Copyright.  Public Domain
  9.     :Language.   Modula-2
  10.     :Translator. M2Amiga A+L V3.2d
  11.     :Imports.    BigSets, TaskMemory [bne]
  12.     :History.    V1.0 [bne] 02.Jul.1989
  13.     :History.    V1.1 [bne] 09.Jul.1989 (TYPEs optimized, bugs fixed)
  14.  
  15. **********************************************************************)
  16.  
  17. IMPLEMENTATION MODULE Clusters;
  18.  
  19. FROM BigSets    IMPORT BigSet, CreateBigSet, DiscardBigSet, Exclude,
  20.                        FindNextClear, Include;
  21. FROM SYSTEM     IMPORT ADDRESS, ADR;
  22. IMPORT TaskMemory;
  23.  
  24. TYPE
  25.   ClusterPtrPtr=POINTER TO ClusterPtr;
  26.  
  27. CONST
  28.   PtrSize=SIZE(ClusterPtrPtr);
  29.  
  30. VAR
  31.   AllocProc: AllocationProc;
  32.   DeallocProc: DeallocationProc;
  33.   Dummy: BOOLEAN;
  34.  
  35. PROCEDURE Reset;
  36.   BEGIN
  37.     AllocProc:=TaskMemory.Allocate;
  38.     DeallocProc:=TaskMemory.Deallocate;
  39.     NumHeaps:=0;
  40.   END Reset;
  41.  
  42. PROCEDURE InitMemManager(Allocation: AllocationProc;
  43.                          Deallocation: DeallocationProc;
  44.                          ClusterSize: LONGINT;
  45.                          BlockSizes: ARRAY OF LONGINT): BOOLEAN;
  46.   VAR
  47.     HeapNum:CARDINAL;
  48.     CurrentHeap:HeapPtr;
  49.   BEGIN
  50.     AllocProc:=Allocation;
  51.     DeallocProc:=Deallocation;
  52.     NumHeaps:=HIGH(BlockSizes)+1;
  53.     AllocProc(HeapArray, NumHeaps*SIZE(Heap));
  54.     IF HeapArray#NIL THEN
  55.       CurrentHeap:=HeapArray;
  56.       FOR HeapNum:=0 TO HIGH(BlockSizes) DO
  57.         WITH CurrentHeap^ DO
  58.           clusterList:=NIL;
  59.           firstFreeCluster:=NIL;
  60.           clusterSize:=ClusterSize;
  61.           blockSize:=BlockSizes[HeapNum]+PtrSize;
  62.           blocksPerCluster:=(clusterSize-SIZE(Cluster)) DIV blockSize;
  63.         END;
  64.         INC(CurrentHeap, SIZE(Heap));
  65.       END;
  66.       RETURN TRUE;
  67.     ELSE
  68.       Reset;
  69.       RETURN FALSE;
  70.     END;
  71.   END InitMemManager;
  72.  
  73. PROCEDURE Allocate(VAR Pointer: ADDRESS;
  74.                        Size: LONGINT);
  75.   VAR
  76.     CurrentHeap: HeapPtr;
  77.     FirstAddress: ClusterPtrPtr;
  78.  
  79.   PROCEDURE FindHeap(): BOOLEAN;
  80.     VAR
  81.       HeapNum: CARDINAL;
  82.     BEGIN
  83.       CurrentHeap:=HeapArray;
  84.       FOR HeapNum:=1 TO NumHeaps DO
  85.         IF CurrentHeap^.blockSize=Size THEN
  86.           RETURN TRUE
  87.         END;
  88.         INC(CurrentHeap, SIZE(Heap));
  89.       END;
  90.       RETURN FALSE;
  91.     END FindHeap;
  92.  
  93.   PROCEDURE AddCluster(): BOOLEAN;
  94.     VAR
  95.       Pred, Node: ClusterPtr;
  96.     BEGIN
  97.       WITH CurrentHeap^ DO
  98.         AllocProc(firstFreeCluster, clusterSize);
  99.         IF firstFreeCluster#NIL THEN
  100.           WITH firstFreeCluster^ DO
  101.             heap:=CurrentHeap;
  102.             firstFreeBlock:=0;
  103.             freeBlocks:=blocksPerCluster;
  104.             IF CreateBigSet(blockAllocMap, blocksPerCluster) THEN
  105.               (* scan list to find the right place *)
  106.               Pred:=ADR(clusterList);
  107.               Node:=clusterList;
  108.               WHILE (Node#NIL) AND
  109.                     (LONGINT(Node)<LONGINT(firstFreeCluster)) DO
  110.                 Pred:=Node;
  111.                 Node:=Node^.next;
  112.               END;
  113.               (* insert new cluster into Heap.clusterList *)
  114.               next:=Node;
  115.               IF next#NIL THEN
  116.                 next^.pred:=firstFreeCluster;
  117.               END;
  118.               Pred^.next:=firstFreeCluster;
  119.               pred:=Pred;
  120.               RETURN TRUE
  121.             END;
  122.           END;
  123.           DeallocProc(firstFreeCluster);
  124.         END;
  125.       END;
  126.       RETURN FALSE;
  127.     END AddCluster;
  128.  
  129.   BEGIN
  130.     INC(Size, PtrSize);
  131.     IF FindHeap() THEN
  132.       WITH CurrentHeap^ DO
  133.         IF firstFreeCluster=NIL THEN
  134.           IF NOT AddCluster() THEN
  135.             Pointer:=NIL;
  136.             RETURN
  137.           END;
  138.         END;
  139.         WITH firstFreeCluster^ DO
  140.           (* allocate block *)
  141.           Include(blockAllocMap, firstFreeBlock);
  142.           FirstAddress:=ADDRESS(LONGINT(firstFreeCluster)+SIZE(Cluster)+
  143.                                 blockSize*LONGINT(firstFreeBlock));
  144.           FirstAddress^:=firstFreeCluster;
  145.           Pointer:=LONGINT(FirstAddress)+PtrSize;
  146.           DEC(freeBlocks);
  147.         END;
  148.         (* search next free block *)
  149.         LOOP
  150.           IF firstFreeCluster^.freeBlocks=0 THEN
  151.             (* no more free blocks in this cluster *)
  152.             firstFreeCluster:=firstFreeCluster^.next;
  153.             IF firstFreeCluster=NIL THEN
  154.               (* no more free blocks in this heap *)
  155.               EXIT
  156.             END;
  157.           ELSE
  158.             WITH firstFreeCluster^ DO
  159.               Dummy:=FindNextClear(blockAllocMap, firstFreeBlock);
  160.             END;
  161.             EXIT
  162.           END;
  163.         END;
  164.       END;
  165.     ELSE
  166.       (* allocate independent block *)
  167.       AllocProc(FirstAddress, Size);
  168.       IF FirstAddress#NIL THEN
  169.         FirstAddress^:=NIL;
  170.         Pointer:=LONGINT(FirstAddress)+PtrSize;
  171.       ELSE
  172.         Pointer:=NIL;
  173.       END;
  174.     END;
  175.   END Allocate;
  176.  
  177. PROCEDURE Deallocate(VAR Pointer: ADDRESS);
  178.   VAR
  179.     CurrentBlock: CARDINAL;
  180.     CurrentCluster: ClusterPtr;
  181.   BEGIN
  182.     CurrentBlock:=FindBlock(Pointer, CurrentCluster);
  183.     IF CurrentCluster#NIL THEN
  184.       Pointer:=NIL;
  185.       WITH CurrentCluster^ DO
  186.         WITH heap^ DO
  187.           (* deallocate block *)
  188.           Exclude(blockAllocMap, CurrentBlock);
  189.           INC(freeBlocks);
  190.           IF freeBlocks#blocksPerCluster THEN
  191.             (* restore <firstFreeBlock> *)
  192.             IF (CurrentBlock<firstFreeBlock) OR (freeBlocks=1) THEN
  193.               firstFreeBlock:=CurrentBlock;
  194.             END;
  195.             (* restore <firstFreeCluster> *)
  196.             IF (LONGINT(CurrentCluster)<LONGINT(firstFreeCluster)) OR
  197.                (firstFreeCluster=NIL) THEN
  198.               firstFreeCluster:=CurrentCluster;
  199.             END;
  200.           ELSE
  201.             (* remove cluster from Heap.clusterList *)
  202.             pred^.next:=next;
  203.             IF next#NIL THEN
  204.               next^.pred:=pred;
  205.             END;
  206.             (* restore <firstFreeCluster> *)
  207.             IF firstFreeCluster=CurrentCluster THEN
  208.               firstFreeCluster:=next;
  209.               WHILE (firstFreeCluster#NIL) AND
  210.                     (firstFreeCluster^.freeBlocks=0) DO
  211.                 firstFreeCluster:=firstFreeCluster^.next;
  212.               END;
  213.             END;
  214.             (* delete cluster *)
  215.             DiscardBigSet(blockAllocMap);
  216.             DeallocProc(CurrentCluster);
  217.           END;
  218.         END;
  219.       END;
  220.     ELSE
  221.       (* deallocate independent block *)
  222.       DEC(Pointer, PtrSize);
  223.       DeallocProc(Pointer);
  224.     END;
  225.   END Deallocate;
  226.  
  227. PROCEDURE FindBlock(    Block: ADDRESS;
  228.                     VAR ClPtr: ClusterPtr): CARDINAL;
  229.   VAR
  230.     FirstAddress: ClusterPtrPtr;
  231.     BlockSize: LONGINT;
  232.   BEGIN
  233.     DEC(Block, PtrSize);
  234.     FirstAddress:=Block;
  235.     ClPtr:=FirstAddress^;
  236.     IF ClPtr#NIL THEN
  237.       DEC(Block, LONGINT(ClPtr));
  238.       DEC(Block, SIZE(Cluster));
  239.       BlockSize:=ClPtr^.heap^.blockSize;
  240.       RETURN LONGINT(Block) DIV BlockSize;
  241.     END;
  242.     RETURN 0;
  243.   END FindBlock;
  244.  
  245. BEGIN
  246.   Reset;
  247. END Clusters.
  248.  
  249.